package com.niiwoo.civet.trade.service.local.contract;

import com.alibaba.dubbo.config.annotation.Reference;
import com.dangdang.ddframe.rdb.sharding.api.HintManager;
import com.dangdang.ddframe.rdb.sharding.hint.HintManagerHolder;
import com.niiwoo.civet.trade.dao.entity.FadadaContractTemplateFile;
import com.niiwoo.civet.trade.dao.entity.Project;
import com.niiwoo.civet.trade.dao.entity.ProjectContract;
import com.niiwoo.civet.trade.dao.entity.ProjectInvestOrder;
import com.niiwoo.civet.trade.dao.mapper.ProjectInvestOrderMapperExt;
import com.niiwoo.civet.trade.service.local.contract.vo.RiskContractDTO;
import com.niiwoo.civet.user.dto.request.SimpleOrgInfo;
import com.niiwoo.civet.user.dto.response.UserAuthorizationInfoResponseDTO;
import com.niiwoo.civet.user.dto.response.UserIdentityInfoResponseDTO;
import com.niiwoo.civet.user.service.OrganizationDubboService;
import com.niiwoo.civet.user.service.UserAuthorizationInfoDubboService;
import com.niiwoo.civet.user.service.UserIdentityDubboService;
import com.niiwoo.tripod.fadada.dto.request.GenerateContractRequestDTO;
import com.niiwoo.tripod.fadada.dto.request.GenerateContractRequestDTO.DynamicTable;
import com.niiwoo.tripod.fadada.dto.response.FadadaResponseDTO;
import com.niiwoo.tripod.fadada.enums.SignClientRoleEnum;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 风险提示书
 * 
 * @author liaojunjun
 *
 */
@Service
public class RiskPrompt extends AbstractFadadaContract {

	private static final Logger logger = LoggerFactory.getLogger(RiskPrompt.class);

	@Autowired
	private SnowflakeIdWorker snowflakeIdWorker;

	@Reference(version = "1.0.0")
	private UserIdentityDubboService userIdentityDubboService;

	@Reference(version = "1.0.0")
	private UserAuthorizationInfoDubboService userAuthorizationInfoDubboService;

	@Autowired
	private ProjectInvestOrderMapperExt projectInvestOrderMapperExt;

	@Reference(version = "1.0.0")
    private OrganizationDubboService organizationDubboService;

	@Override
	public ProjectContract contractHandler(FadadaContractTemplateFile contractTemplate, String bizContractNo,
			Project project, String userId) throws Exception {
		logger.info("风险提示书处理开始... projectId:{}", project.getProjectId());

		// 构建风险提示书所需数据
		RiskContractDTO riskContractDTO = buildRiskContractDTO(userId, project);

		this.generateContract(contractTemplate, riskContractDTO);

		ProjectContract result = this.signContract(contractTemplate, riskContractDTO);

		this.contractFilling(riskContractDTO.getContractId());
		logger.info("风险提示书处理结束... projectId:{}", project.getProjectId());
		return result;
	}

	/**
	 * 构建风险提示书所需数据
	 * @param userId
	 * @param project
	 * @return
	 */
	private RiskContractDTO buildRiskContractDTO(String userId, Project project) {
		// 构建风险合同数据
		RiskContractDTO riskContractDTO = new RiskContractDTO();
		riskContractDTO.setContractId(snowflakeIdWorker.nextId() + "");
		riskContractDTO.setProjectId(project.getProjectId());
		riskContractDTO.setInvestUserId(userId);

		// 借款人信息
		if (!HintManagerHolder.isMasterRouteOnly()) {
			HintManager hintManager = HintManager.getInstance();
			hintManager.setMasterRouteOnly();
		}
		List<ProjectInvestOrder> list = projectInvestOrderMapperExt.selectInvestOrderListByProjectIdAndUserId(userId, project.getProjectId());
		ProjectInvestOrder projectInvestOrder = list.get(0);
		if (projectInvestOrder.getInvestorType() == 1) { //个人
			UserIdentityInfoResponseDTO userIdentityInfo = userIdentityDubboService.get(userId);
			if (userIdentityInfo == null){
				throw new BizException("TRD10005", "风险提示书处理异常 userIdentityInfo is null");
			}

			riskContractDTO.setInvestUserName(userIdentityInfo.getName());
			UserAuthorizationInfoResponseDTO userAuthorizationInfo = userAuthorizationInfoDubboService.getUserAuthorizationInfo(userId);
			riskContractDTO.setFadadaCacertId(userAuthorizationInfo.getFadadaCacertId()); // 授权信息(CA证书编号)
		} else { //企业
			SimpleOrgInfo orgInfo = organizationDubboService.getByOrgId(userId);
			if (orgInfo == null){
				throw new BizException("TRD10005", "风险提示书处理异常 orgInfo is null");
			}
			riskContractDTO.setInvestUserName(orgInfo.getOrganizationName());
			riskContractDTO.setFadadaCacertId(orgInfo.getFadadaCacertId()); // 法大大证书ID 授权信息(CA证书编号)
		}
		return riskContractDTO;
	}

	private void generateContract(FadadaContractTemplateFile contractTemplate, RiskContractDTO riskContractDTO) throws Exception {
		logger.info("风险提示书生成开始... projectId:{}", riskContractDTO.getProjectId());

		GenerateContractRequestDTO dto = new GenerateContractRequestDTO();

		dto.setContractId(riskContractDTO.getContractId());
		dto.setDocTitle(contractTemplate.getTemplateName());
		dto.setTemplateId(contractTemplate.getTemplateId());

		Map<String, String> parameterMap = new HashMap<String, String>();

		parameterMap.put("investorName", "出借人：" + riskContractDTO.getInvestUserName());
		parameterMap.put("signDate", DateFormatUtils.format(new Date(), "yyyy年MM月dd日"));

		// 投资人姓名列表
		// 表格header
		List<String> headers = new ArrayList<>();
		headers.add("");

		DynamicTable signNameTable = new DynamicTable();
		signNameTable.setInsertWay(1);
		signNameTable.setKeyword("本人自愿承担因网络借贷行为带来的一切风险和责任。");
		signNameTable.setCellHeight(60f);
		signNameTable.setHeaders(headers);
		// 签名时需要增加高度并居中显示
		signNameTable.setCellVerticalAlignment(5);
		signNameTable.setBorderFlag(false);
		List<DynamicTable> tables = new ArrayList<DynamicTable>();
		tables.add(signNameTable);

		dto.setDynamicTables(tables);
		dto.setParameterMap(parameterMap);

		generateContract(dto);
		logger.info("风险提示书生成结束... projectId:{}", riskContractDTO.getProjectId());
	}

	private ProjectContract signContract(FadadaContractTemplateFile contractTemplate, RiskContractDTO dto) throws Exception {
		String METHOD_NAME = "法大大合同自动签署-风险提示书 projectId:" + dto.getProjectId();
		logger.info(METHOD_NAME);

		String docTitle = dto.getInvestUserName() + "的风险提示书_" + dto.getContractId();

		// 投资人签署
		String transactionId = snowflakeIdWorker.nextId() + "";
		String borrowerCaCertId = dto.getFadadaCacertId();
		String borrowerSignKeyword = "出借人：" + dto.getInvestUserName();
		FadadaResponseDTO fadadaResponse = extSignAuto(transactionId, dto.getContractId(), borrowerCaCertId,
				SignClientRoleEnum.BORROWER.getValue(), docTitle, borrowerSignKeyword);
		logger.info("法大大合同自动签署-风险提示书 投资人签署结束... projectId:{}", dto.getProjectId());
		return this.buildContractUpdateRecord(contractTemplate.getTemplateId(), dto.getContractId(), transactionId,
				fadadaResponse.getViewUrl(), fadadaResponse.getDownloadUrl());
	}

}
